﻿using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class SpawnPool : MonoBehaviour
{
    #region  成员变量
    //当前脚本所挂接的游戏对象的transform组件
    Transform m_Group;
    //PrefabPool对象集合
    private List<PrefabPool> m_PrefabPool = new List<PrefabPool>();
    #endregion

    #region  系统接口
    void Awake()
    {
        m_Group = transform;
    }
    #endregion

    #region 激活对象
    public Transform Spawn(Transform trans,Vector3 sc,Vector3 pos=default(Vector3), Quaternion rot=default(Quaternion))
    {
        Transform inst;
        pos = transform.InverseTransformPoint(pos);
        //遍历列表
        for (int i = 0; i < m_PrefabPool.Count; i++)
        {
            //判断是否有该游戏对象的prefabpool
            if (m_PrefabPool[i].m_obj == trans.gameObject)
            {
                //有的话激活游戏对象(或者创建游戏对象)
                inst = m_PrefabPool[i].SpawnInstance(pos, rot,sc);
                //统一设置inst的父亲为当前脚本所挂接的游戏对象
                inst.SetParent(m_Group);
                return inst;
            }
        }
        //遍历列表没有该游戏对象的prefabpool，新建一个prefabpool并激活游戏对象
        PrefabPool prefabPool = new PrefabPool(trans)
        {
            sp = this
        };
        m_PrefabPool.Add(prefabPool);
        //spawn出我们想要的游戏对象
        inst = prefabPool.SpawnInstance(pos, rot ,sc);
        //设置父亲
        inst.SetParent(m_Group);
        return inst;
    }
    #endregion

    #region 失活对象
    public void Despawn(Transform DesTrans)
    {
        bool Despawned = false;
        for (int i = 0; i < m_PrefabPool.Count; i++)
        {
            //寻找该游戏对象的prefabpool
            if (m_PrefabPool[i].m_lSpawn.Contains(DesTrans))
                Despawned = m_PrefabPool[i].DespawnInstance(DesTrans);
            else if (m_PrefabPool[i].m_lDespawn.Contains(DesTrans))
                return;
        }
        if (!Despawned)
            return;
    }
    #endregion

    #region PrefabPool类
    //创建PrefabPool类
    public class PrefabPool
    {
        //预制体transform组件
        public Transform m_trans;
        //GameObject
        public GameObject m_obj;
        //所在的对象池
        public SpawnPool sp;
        //Spawn列表
        public List<Transform> m_lSpawn = new List<Transform>();
        //Despawn列表
        public List<Transform> m_lDespawn = new List<Transform>();
        //构造函数
        public PrefabPool(Transform prefab)
        {
            m_trans = prefab;
            m_obj = prefab.gameObject;
        }
        //激活对象
        public Transform SpawnInstance(Vector3 pos, Quaternion rot,Vector3 sc)
        {
            Transform inst;
            //如果失活列表的数量为零，新建游戏对象
            if (0 == m_lDespawn.Count)
                inst = SpawnNew(pos, rot,sc);
            //如果失活列表的数量不为零，失活列表0号元素的游戏对象活性开启，从失活列表移除，添加到活性列表
            else
            {
                inst = m_lDespawn[0];
                m_lDespawn.RemoveAt(0);
                m_lSpawn.Add(inst);
                inst.position = pos/100;
                inst.localScale = sc;
                inst.gameObject.SetActive(true);
            }
            return inst;
        }
        //创建新的对象
        Transform SpawnNew(Vector3 pos, Quaternion rot,Vector3 sc)
        {
            Transform inst = Instantiate(m_trans, pos, rot);
            inst.name = m_trans.name;
            inst.gameObject.GetOrAddComponent<SphereTranslate>();
            inst.position /= 100;
            inst.localScale = sc/100;
            m_lSpawn.Add(inst);
            return inst;
        }
        //失活对象, 活性列表的0号元素活性打开，并从活性列表移除，添加到失活列表
        public bool DespawnInstance(Transform trans)
        {
            trans.gameObject.SetActive(false);
            m_lDespawn.Add(trans);
            m_lSpawn.Remove(trans);
            return true;
        }
    }
    #endregion
}